package com.hzit.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.hzit.dto.StudentDTO;
import com.hzit.entity.Classes;
import com.hzit.entity.PageResult;
import com.hzit.entity.Student;
import com.hzit.entity.StudentExample;
import com.hzit.mapper.ClassesMapper;
import com.hzit.mapper.StudentMapper;
import com.hzit.service.StudentService;
import com.hzit.vo.StudentVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.List;

/**
 * 类名：
 * 作者：WF
 * 功能：
 */
@Service          // 一般用在service层
//@Repository     // 一般在dao层放bean到spring容器中
//@Component      // 一般在组件功能未确定或者除了（dao或service层），如：拦截器、springBoot配置类。。。
//@Controller     // 一般用在控制器层
public class StudentServiceImpl implements StudentService {

	/**
	 * 之所以可以在spring容器中取得这个mapper，是因为在 applicationContext.xml文件中有如下配置：
	 *   <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	 *         <property name="basePackage" value="com.hzit.mapper"/>
	 *   </bean>
	 */
	@Autowired
	private StudentMapper studentMapper;
	@Autowired
	private ClassesMapper classesMapper;

	public StudentServiceImpl(){
		System.out.println("构造方法。。。");
	}
	//1. 查询所有学生
	@Override
	public List<Student> findAll() {
		return studentMapper.selectByExample(null);
	}


	//2. 初始化注解，相当于bean标签中的init-method属性。
	@PostConstruct
	public void init(){
		System.out.println("StudentServiceImpl init...");
	}
	//3. 销毁对象时，相当于bean标签中的destroy-method属性。
	@PreDestroy
	public void destroy(){
		System.out.println("StudentServiceImpl destroy...");
	}
	//4. 开始分页查询
	@Override
	public PageResult<StudentDTO> findByPage(int page, int pageSize) {
		//4.1 开始分页
		PageHelper.startPage(page,pageSize);
		//4.2 开始查询
		StudentExample example = new StudentExample();
		List<Student> students = studentMapper.selectByExample(example);
		//4.3 转换为Page<Student>对象
		Page<Student> studentPage = (Page<Student>) students;
		//4.4 得到分页的结果集对象
		List<Student> result = studentPage.getResult();
		//4.5 遍历结果集对象
		List<StudentDTO> studentVos = new ArrayList<>();
		result.forEach(rs -> {
			//4.5.1 定义目标对象
			StudentDTO dto = new StudentDTO();
			//4.5.2 拷贝原对象rs到目标对象vo中
			BeanUtil.copyProperties(rs,dto,true);
			//4.5.3 设置目标对象vo的班级名称
			Classes classes = classesMapper.selectByPrimaryKey(rs.getCid());
			dto.setCname(classes.getCname());
			//4.5.4 将目标对象vo添加到集合中
			studentVos.add(dto);
		});
		//4.6 返回
		return new PageResult<>(studentPage.getTotal(),studentVos);
	}

	//5. 条件带分页查询
	// 相比较findByPage()方法，增加了查询条件过程，代码集中在：106-120
	@Override
	public PageResult<StudentDTO> search(int page, int pageSize, StudentVo vo) {
		//4.1 开始分页
		PageHelper.startPage(page,pageSize);
		//4.2 开始查询
		StudentExample example = new StudentExample();
		//4.2.1 构造查询条件
		StudentExample.Criteria criteria = example.createCriteria();
		//4.2.2 根据传入的vo对象，构造不同的查询条件
		if(vo != null){
			if(StrUtil.isNotBlank(vo.getSname())){
				criteria.andSnameLike("%" + vo.getSname() + "%");
			}
			if(StrUtil.isNotBlank(vo.getAddr())){
				criteria.andAddrLike("%" + vo.getAddr() + "%");
			}
			if(vo.getCid() != null && vo.getCid() != 0){
				criteria.andCidEqualTo(vo.getCid());
			}
		}
		List<Student> students = studentMapper.selectByExample(example);
		//4.3 转换为Page<Student>对象
		Page<Student> studentPage = (Page<Student>) students;
		//4.4 得到分页的结果集对象
		List<Student> result = studentPage.getResult();
		//4.5 遍历结果集对象
		List<StudentDTO> studentVos = new ArrayList<>();
		result.forEach(rs -> {
			//4.5.1 定义目标对象
			StudentDTO dto = new StudentDTO();
			//4.5.2 拷贝原对象rs到目标对象vo中
			BeanUtil.copyProperties(rs,dto,true);
			//4.5.3 设置目标对象vo的班级名称
			Classes classes = classesMapper.selectByPrimaryKey(rs.getCid());
			dto.setCname(classes.getCname());
			//4.5.4 将目标对象vo添加到集合中
			studentVos.add(dto);
		});
		//4.6 返回
		return new PageResult<>(studentPage.getTotal(),studentVos);
	}

	//5. 保存学重复
	@Override
	public void save(Student student) {
		studentMapper.insert(student);
	}


	//6. 修改学生1
	// update student set sname=?,sex=?,age=?,addr=?,cid=?,birth=? where cid=?
	// 比较：updateByPrimaryKeySelective()与updateByPrimaryKey()区别：
	public void update1() {
		Student student = new Student();
		student.setSname("aaa");
		student.setAddr("上海");
		// 这个方法，只对传入的属性值进行修改,没有传入的不做修改
		studentMapper.updateByPrimaryKeySelective(student);
		// 这个方法，对传入的属性进行修改，没有传入的字段属性改为null
		studentMapper.updateByPrimaryKey(student);
	}

	/**
	 * 7. 修改学生2
	 * 这种情况的修改，因为前端己将学生对象的所有属性传入，所以，使用
	 * updateByPrimaryKeySelective()与updateByPrimaryKey()结果是一样的！
	 * @param student
	 */
	@Override
	public void update(Student student) {
		studentMapper.updateByPrimaryKeySelective(student);
	}

	//8. 删除学生
	@Override
	public void delete(String sid) {
		studentMapper.deleteByPrimaryKey(Integer.parseInt(sid));
	}
}
